<template>
  <div class="container">
    <div class="flip-clock-card" :style="clockStyle">
      <!-- 时 -->
      <FlipNumberCard ref="hoursCardRef" :scale="config.scale" :contents="hoursText" :cardStyle="cardStyle" />
      <!-- 间隔 -->
      <ClockSeparator :scale="config.scale" :color="config.separatorColor" />
      <!-- 分 -->
      <FlipNumberCard ref="minutesCardRef" :scale="config.scale" :contents="minutesText" :cardStyle="cardStyle" />
      <!-- 间隔 -->
      <ClockSeparator :scale="config.scale" :color="config.separatorColor" />
      <!-- 秒 -->
      <FlipNumberCard ref="secondsCardRef" :scale="config.scale" :contents="secondsText" :cardStyle="cardStyle" />
      <!-- 提示文字 -->
      <div class="tipsText">{{ tipsText }}</div>
    </div>
  </div>
</template>
<script setup>
import { ref, nextTick, reactive, watch, onMounted, computed } from "vue";
import FlipNumberCard from "./FlipNumberCard.vue";
import { formatSecondsForHMS } from "@/utils/date";
import ClockSeparator from "./ClockSeparator.vue";

/**
 * 剩余时间
 */
const remainingTime = ref(0);

/**
 * 提示
 */
const tipsText = ref("");

/**
 * 翻转数字卡片引用
 */
const hoursCardRef = ref(null);
const minutesCardRef = ref(null);
const secondsCardRef = ref(null);

/**
 * 上一个时分秒文本
 */
let lastHoursText = ref(formatSecondsForHMS(remainingTime.value, "HH"));
let lastMinutesText = ref(formatSecondsForHMS(remainingTime.value, "mm"));
let lastSecondsText = ref(formatSecondsForHMS(remainingTime.value, "ss"));

/**
 * 翻转数字卡片所需要展示的内容
 */
const hoursText = ref([lastHoursText]);
const minutesText = ref([lastMinutesText]);
const secondsText = ref([lastSecondsText]);

// 响应式数据定义
const config = reactive({
  fontColor: "#fef400", // 字体颜色
  cardBackgroundColor: "#a366da", // 背景颜色
  dividerColor: "rgba(77, 18, 130, 0.5)", // 分割线颜色
  separatorColor: "rgba(77, 18, 130, 0.3)", //间隔线颜色
  clockBackgroundColor: "rgba(77, 18, 130, 0.3)", //时钟背景颜色
  scale: 1, //缩放比例
});

/**
 * 时钟卡片样式
 */
const cardStyle = computed(() => {
  return {
    fontColor: config.fontColor,
    backgroundColor: config.cardBackgroundColor,
    dividerColor: config.dividerColor,
  };
});

/**
 * 切换标志
 */
let flag = true;

/**
 * 时钟样式
 */
const clockStyle = computed(() => {
  return {
    "--clock-background-color": config.clockBackgroundColor,
    "--clock-tips-text-color": config.scale,
  };
});

/**
 * 翻到下一页
 * 底层是通过删除一个card的所有active和before，再为老card添加before，为新的card添加active，实现的动画
 * 本质上执行的都是从是上一个card切换到下一个card的动画，所以翻转卡片中理论上只需要2张卡片即可，没必要全部实例化出来
 * 如果翻转卡片中的实例卡片过多，性能可能会下降，还占用内存
 * 每次仅仅删除上一次的2张卡片，再加入下一次的2张卡片，再执行动画会失败
 * vue会缓存一定时期里的变化再渲染，导致class类看起来并没有变化，所以不会执行动画
 * 所以flag=true时卡片class为：【before,active】，flag=false时卡片class为：【XX,before,active】
 * 通过错位，让第n个卡片前后的class不一致，vue才会成功渲染，并执行动画
 */
const flip = (ref, text, lastText, newText) => {
  if (lastText.value !== newText) {
    if (flag) {
      text.value = [lastText.value, newText];
      nextTick(() => {
        ref.value.flipByIndex(0, 1);
      });
    } else {
      text.value = [lastText.value, lastText.value, newText];
      nextTick(() => {
        ref.value.flipByIndex(1, 2);
      });
    }
    lastText.value = newText;
  }
};

/**
 * 监听剩余时间变化
 */
watch(remainingTime, () => {
  const newHours = formatSecondsForHMS(remainingTime.value, "HH");
  const newMinutes = formatSecondsForHMS(remainingTime.value, "mm");
  const newSeconds = formatSecondsForHMS(remainingTime.value, "ss");

  flip(hoursCardRef, hoursText, lastHoursText, newHours);
  flip(minutesCardRef, minutesText, lastMinutesText, newMinutes);
  flip(secondsCardRef, secondsText, lastSecondsText, newSeconds);

  flag = !flag;
});

/**
 * 监听配置修改
 */
window.services.ipcRenderer.on("update-setting", (event, settings) => {
  config.scale = settings.clockSizeScale;
});

/**
 * 监听提示文字变化
 */
window.services.ipcRenderer.on("update-tips-text", (event, text) => {
  tipsText.value = text;
});

/**
 * 修改剩余时间请求监听
 */
window.services.ipcRenderer.on("update-remainingTime", (event, time) => {
  remainingTime.value = time;
});

/**
 * 监听时钟主题配置修改
 */
window.services.ipcRenderer.on("update-clock-theme", (event, clockTheme) => {
  config.fontColor = clockTheme.fontColor;
  config.cardBackgroundColor = clockTheme.cardBackgroundColor;
  config.dividerColor = clockTheme.dividerColor;
  config.separatorColor = clockTheme.separatorColor;
  config.clockBackgroundColor = clockTheme.clockBackgroundColor;
});

/**
 * 通知父组件已启动
 */
onMounted(() => {
  utools.sendToParent("child-started");
});
</script>
<style scoped lang="scss">
.container {
  .flip-clock-card {
    position: relative;
    width: fit-content;
    background: var(--clock-background-color);
    padding: 20px;
    border-radius: 10px;
    display: flex;

    .tipsText {
      -webkit-user-select: none; //禁止选择文字
      width: 100%;
      font-size: 14px;
      color: #888;
      text-align: center;
      position: absolute;
      bottom: -20px;
      left: 50%;
      transform: translateX(-50%);
    }
  }
}
</style>
